home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Technotools
/
Technotools (Chestnut CD-ROM)(1993).ISO
/
lang_asm
/
asm_kit
/
hercules.asm
< prev
next >
Wrap
Assembly Source File
|
1985-12-08
|
13KB
|
563 lines
;*********************************************
; * HERCULES GRAPHICS CARD UTILITY ROUTINES *
; * graph_mode(),text_mode(),plot(x,y) *
;*********************************************
;****************************************************************************
;* graph_mode() : puts the hercules graphics card into its graphics mode
;****************************************************************************
; ******** hercules port addresses ********
INDEX_PORT equ 03b4H
CTL_PORT equ 03b8H
CONFIG_PORT equ 03BFH
; ******** hercules ctl codes **********
SCRN_ON equ 8
GRPH equ 2
TEXT equ 20H
FULL_MODE equ 03H
DSEG
gtable db 35H,2DH,2EH,07H
db 5BH,02H,57H,57H
db 02H,03H,00H,00H
ttable db 61H,50H,52H,0FH
db 19H,06H,19H,19H
db 02H,0DH,0BH,0CH
video_page_base_ dw 0,0B000H ;double-word addr= B000:0000H
public cursor_x_,cursor_y_,grph_attrib_
cursor_x_ dw 0
cursor_y_ dw 0
grph_attrib_ db 0
CSEG
setmd_:
; sets mode to graphics or TEXT
; depending on al
; si=parameter table
; cx=number of words to be cleared
; bx=blank value
push ds
push es
push ax ;push mode
push bx ;push blank value
push cx ;push # of words to be cleared
mov dx,CTL_PORT ;change mode but without SCRN_ON
out dx,al
mov ax,ds ;point es:si to parameter table
mov es,ax
mov dx,INDEX_PORT
mov cx,12 ;12 parameters to be output
xor ah,ah ;starting from reg 0
parms: mov al,ah
out dx,al
inc dx
lodsb
out dx,al ; output data from table
inc ah
dec dx
loop parms
pop cx ;clear the buffer
mov ax,0b000h
cld ;setting up for string instruction here
mov es,ax
xor di,di
pop ax
rep stosw
mov dx,CTL_PORT ;turn scrn on, point to page 0
pop ax
add al,SCRN_ON
out dx,al
pop es
pop ds
ret
;****************************************************************************
;* graph_mode() : puts the hercules graphics card into its graphics mode
;****************************************************************************
CSEG
public graph_mode_
graph_mode_:
push bp
push es
mov al,FULL_MODE
mov dx,CONFIG_PORT
out dx,al ;HGC FULL
mov al,GRPH
lea si,gtable
mov bx,0
mov cx,4000h
call setmd_
pop es
pop bp
ret
;****************************************************************************
;* TEXT_mode() : puts the hercules graphics card into TEXT mode
;****************************************************************************
public TEXT_mode_
TEXT_mode_:
push bp
push es
mov al,TEXT
lea si,ttable
mov bx,720h
mov cx,2000
call setmd_
pop es
pop bp
ret
;****************************************************************************
;* plot(x,y) lights the pixel located at coordinates x,y
;* Hercules graphics card version....
;****************************************************************************
;byte-addr = [2000H + (Ymod4)] + [90*INT(Y/4)] + INT(X/8)
;bit-offset = 7-(Xmod8)
public plot_
plot_: ;scrambles ax,bx,cx,dx,es
push bp
mov bp,sp
mov ax,[bp+6] ;y in bx
and ax,0003H ;(Ymod4) in bx
mov bx,2000H
mul bx ;(Ymod4)*2000H in ax
mov bx,ax ;(Ymod4)*2000H in bx
mov ax,[bp+6]
shr ax,1
shr ax,1 ;int(y/4) in ax
mov cx,90 ;can't multiply by immediate
mul cx ;int(y/4) * 90 in ax
add bx,ax ;[int(y/4) * 90]+[(Ymod4)+2000H] in bx
mov ax,[bp+4] ;x in ax
shr ax,1
shr ax,1
shr ax,1 ;int(x/8) in bx
add ax,bx ;whole byte offset address in ax
les bx,video_page_base_ ;es:bx points to video base
add bx,ax ;entire address in es:bx
mov ax,[bp+4] ;X in ax
and ax,0000000000000111B ;Xmod8 in ax
mov cl,al ;Xmod8 becomes shift count
mov al,10000000B ;start from the top
shr al,cl ;bit pos is now in al, addr in es:bx
or es:[bx],al ;this one does the deed!
pop bp
ret
;*****************************************
;* init_page_1() copies page 0 into page 1
;*****************************************
public init_page_1_
init_page_1_:
push bp
push es
push si
push di
push ds
mov ax,0B000H
mov es,ax ;es and ds both point to video ram
mov ds,ax ;no working variables... might have to move this one
mov si,0 ;source is page 1
mov di,8000H ;dest is page 2
mov cx,8000H ;xfr 8000 bytes(one graphics page)
cld ;going up...
rep movsb ;do it to it!
pop ds
pop di
pop si
pop es
pop bp
ret
;*****************************************
;* init_page_0() copies page 1 into page 0
;*****************************************
public init_page_0_
init_page_0_:
push bp
push es
push si
push di
push ds
mov ax,0B000H
mov es,ax ;es and ds both point to video ram
mov ds,ax ;no working variables... might have to move this one
mov si,8000H ;source is page 1
mov di,0 ;dest is page 0
mov cx,4000H ;xfr 8000 bytes(one graphics page)
cld ;going up...
rep movsw ;do it to it!
pop ds
pop di
pop si
pop es
pop bp
ret
;*******************************************************************
;* graphics_cls(page) clears the screen when it's in graphics mode *
;*******************************************************************
;1 process graphics_cls
public graphics_cls_
graphics_cls_:
push bp
mov bp,sp ;page# in [bp+4]
;2 if we need to clear page 0
mov ax,[bp+4]
or ax,ax
jnz graphics_cls_1
;3 point at page 0
mov di,0000H
;2 else(we need to clear page 1)
jmp graphics_cls_2
graphics_cls_1:
;3 point at page 1
mov di,8000H
;2 endif(page 0 or 1?)
graphics_cls_2:
;2 set up the rest of the block load
mov ax,0B000H
mov es,ax ;video base addr
mov cx,8000H ;length of page
mov ax,0
cld ;load UP
rep stosb
;2 zero out the graphics cursor
mov ax,0
mov cursor_x_,ax
mov cursor_y_,ax
;1 endprocess graphics_cls
pop bp
ret
;/********************************************************/
; Hercules graphic text drawing routines
;/********************************************************/
include "hercfont.a"
y_table_: ;tells us the starting y offset for a char
;it has one entry for each of the 27 rows
dw 0000H ;letter row 0
dw 210EH ;letter row 1
dw 421CH ;letter row 2
dw 632AH ;letter row 3
dw 0492H ;letter row 4
dw 25A0H ;letter row 5
dw 46AEH ;letter row 6
dw 67BCH ;letter row 7
dw 0924H ;letter row 8
dw 2A32H ;letter row 9
dw 4B40H ;letter row 10
dw 6C4EH ;letter row 11
dw 0DB6H ;letter row 12
dw 2EC4H ;letter row 13
dw 4FD2H ;letter row 14
dw 70E0H ;letter row 15
dw 1248H ;letter row 16
dw 3356H ;letter row 17
dw 5464H ;letter row 18
dw 7572H ;letter row 19
dw 16DAH ;letter row 20
dw 37E8H ;letter row 21
dw 58F6H ;letter row 22
dw 7A04H ;letter row 23
dw 1B6CH ;letter row 24
dw 3C7AH ;letter row 25
CSEG
;*******************************************
;* set plot_tty_cursor(x,y)
;*******************************************
public set_plot_tty_cursor_
set_plot_tty_cursor_:
push bp
mov bp,sp
mov ax,[bp+4]
mov cursor_x_,ax
mov ax,[bp+6]
mov cursor_y_,ax
pop bp
ret
;*******************************************
;1 process plot_char_tty(ascii_char)
public plot_char_tty_
plot_char_tty_:
push bp
mov bp,sp
;2 if this is not a control char
mov al,[bp+4]
and al,07FH
cmp al,20H
jc plot_char_tty_1
;3 output char at current cursor position
mov al,[bp+4]
push ax
mov ax,cursor_y_
push ax
mov ax,cursor_x_
push ax
call plot_char_
add sp,6
;3 increment cursor position
call increment_cursor_
;2 else (ctl char)
jmp plot_char_tty_2
plot_char_tty_1:
;3 if the char is a <CR>
mov al,[bp+4]
cmp al,0Dh
jnz plot_char_tty_3
;4 cursor_x_ = 0
mov ax,0
mov cursor_x_,ax
;3 else if the char is <LF>
jmp plot_char_tty_4
plot_char_tty_3:
cmp al,0AH
jnz plot_char_tty_4
;4 cursor_y_++
mov ax,cursor_y_
inc ax
mov cursor_y_,ax
cmp ax,26 ;line at bottom will roll over to
jc plot_char_tty_5 ;top
mov ax,0
mov cursor_y_,ax
plot_char_tty_5:
;3 endelseif
plot_char_tty_4:
;2 endif(ctl char?)
plot_char_tty_2:
;1 endprocess plot_char_tty
pop bp
ret
;************************************
;* plot_char(x,y,ascii_char)
;* x can be from 0 thru 89 [bp+4] = x,[bp+6]=y,[bp+8]=ascii_char
;* y can be from 0 thru 25
;************************************
;* sets global cursor_x and cursor_y to where it's own parameters
;we have defined font patterns for ascii 20H thru 5AH
;1 process plot_char ;destroys contents of bx,si,ax,es
public plot_char_
plot_char_:
push bp
mov bp,sp
;2 convert the ascii char to a table pointer
mov al,[bp+8]
push ax
call convert_ascii_
add sp,2
mov [bp+8],ax ;table ptr in [bp+8]
;2 point to the beginning of the char in video ram
les bx,video_page_base_ ;es:bx point to video card base
mov bx,[bp+6] ;y in bx
add bx,bx ;two bytes per table entry
mov ax,y_table_[bx] ;address in ax
add ax,[bp+4] ;add in x
mov bx,ax ;es:bx now point to video board char position
mov si,[bp+8] ;ds:si points to table
mov al,[si] ;first byte in al
xor al,grph_attrib_ ;reverse video?
mov es:[bx],al ;out to video
;2 repeat
mov cx,9
plot_char_1:
;3 increment table pointer
inc si
;3 increment video ram pointer
add bx,2000H ;point to next bank
cmp bx,8000H ;do we roll over
jc plot_char_2 ;pop over this next if 8000H bigger
add bx,5AH
and bx,1FFFH ;and referance back down to 1st bank
plot_char_2:
;3 move char pattern out to video ram
mov al,[si]
xor al,grph_attrib_ ;reverse video if grph_attrib=ff
mov es:[bx],al
;2 9 times
loop plot_char_1
;1 endprocess plot_char
pop bp
ret
;1 process convert_ascii
public convert_ascii_
convert_ascii_:
push bp
mov bp,sp ;input parameter = [bp+4]
;2 make input into 7-bit ascii
mov al,[bp+4]
and al,07FH
mov [bp+4],al
;2 if input > bottom-ot-ascii-table -1
cmp al,17H
jc convert_ascii_1
;3 if input < end of ascii table + 1
mov al,[bp+4]
sub al,7BH
jnc convert_ascii_3
;4 just leave it unmolested
;3 else (input > 5BH)
jmp convert_ascii_4
convert_ascii_3:
;4 return space
mov byte [bp+4],20H
;3 endif(input < 5bH?)
convert_ascii_4:
;2 else (input not greater than 1FH)
jmp convert_ascii_2
convert_ascii_1:
;2 return space
mov byte [bp+4],20H
;2 endif
convert_ascii_2:
;2 get the output parameter
mov ax,[bp+4] ;index into table
sub ax,18H ;- offset(18H is first table entry)
mov bx,10 ;times bytes/entry
mul bx ;answer still fits in ax
add ax,offset ascii_table_
;1 endprocess convert_ascii
pop bp
ret
;*******************************************
;1 process plot_string(string)
public plot_string_
plot_string_:
push bp
mov bp,sp
;2 get parameter
mov bx,[bp+4]
;2 get first char
mov al,[bx]
;2 repeat
plot_string_1:
;3 plot_char_tty(char)
push bx
push ax
call plot_char_tty_
add sp,2
pop bx
;3 get next char
inc bx
mov al,[bx]
;2 until character=0
or al,al
jnz plot_string_1
;1 endprocess plot_string
pop bp
ret
;*******************************************
;1 process increment_cursor
public increment_cursor_
increment_cursor_:
push bp
;2 increment cursor_x_ position
mov ax,cursor_x_
inc ax ;cursor_x_+1 in ax
mov cursor_x_,ax
;2 if cursor_x_ got to 80
cmp ax,80
jc increment_cursor_1
;3 cursor_x_ = 0
mov ax,0
mov cursor_x_,ax
;3 cursor_y_++
mov ax,cursor_y_
inc ax
mov cursor_y_,ax
;3 if cursor_y_ = 26
cmp ax,26
jnz increment_cursor_2
;4 cursor_y_ = 0
mov ax,0
mov cursor_y_,ax
;3 endif(cursor_y_= 26?)
increment_cursor_2:
;2 endif(cursor_y_= 80?)
increment_cursor_1:
;1 endprocess increment_cursor_
pop bp
ret